import * as Cesium from 'cesium';
import BaseDraw from './common/BaseDraw';
import * as CesiumCoord from './common/CesiumCrood';
import * as CesiumCaculater from './common/CesiumCaculater';
import GroupEntityCollection from '../../Common/GroupEntityCollection';
import { v4 } from 'uuid';

export default class DrawPolygon extends BaseDraw {
    constructor(viewer, tip) {
        super(viewer);
        this.viewer = viewer;
        this.tip = tip; // 提示DOM
        // 事件对象，每种类型的事件只能注册一次
        this.handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
        this.entityCollection = new GroupEntityCollection(viewer); // 集合
        this.ellipsoid = Cesium.Ellipsoid.WGS84;
    }
    // 重置绘制中间量
    resetDraw() {
        this.groupId = v4(); // 每次绘制的id, 根据此id 进行entity管理
        this.labelEntity = null; // 当次绘制的-标签实例
        this.rectangleEntry = null; // 当次绘制的-矩形实例
        this.positionList = []; // 当次绘制的笛卡尔数组
    }

    getAllEntity() {
        return this.entityCollection.getAllEntities();
    }
    // 关闭 CallbackProperty的计算，取最后一次的结果
    removeCallbackProperty() {
        const rectangleEntry = this.rectangleEntry;
        const labelEntity = this.labelEntity;
        if (rectangleEntry) {
            rectangleEntry.rectangle.coordinates = rectangleEntry.rectangle.coordinates.getValue();

            // console.log("removeCallbackProperty", {
            //   coordinates: this.rectangleEntry.rectangle.coordinates,
            // });
        }
        if (labelEntity) {
            labelEntity.position = labelEntity.position.getValue();
            labelEntity.label.text = labelEntity.label.text.getValue();
        }
    }
    createLabelEntity() {
        const _this = this;
        const positionList = this.positionList;
        const entity = new Cesium.Entity({
            position: new Cesium.CallbackProperty(() => {
                //  两个点确定一个矩形
                if (positionList.length > 1) {
                    // 直接取中点就是 几何中心
                    const p1 = positionList[0];
                    const p2 = positionList[1];
                    const center = new Cesium.Cartesian3(
                        (p1.x + p2.x) / 2,
                        (p1.y + p2.y) / 2,
                        (p1.z + p2.z) / 2
                    );
                    return center;
                } else {
                    return positionList[0];
                }
            }, false),
            label: {
                text: new Cesium.CallbackProperty(() => {
                    // 动态改变标签显示  两个点确定一个矩形
                    if (positionList.length > 1) {
                        const coord = Cesium.Rectangle.fromCartesianArray(positionList);
                        const list = CesiumCoord.rectangleToLatLon(coord); // 转四个顶点的经纬度坐标
                        const polygonPoint = [[...list, list[0]]];
                        const area = CesiumCaculater.area(polygonPoint); // 返回面积
                        if (area > 1000000) {
                            return '面积:' + (area / 1000000).toFixed(2) + '平方公里';
                        } else {
                            return '面积:' + area.toFixed(2) + '平方米';
                        }
                    } else {
                        return '0';
                    }
                }, false),
                font: '20px',
                color: Cesium.Color.RED,
                pixelOffset: new Cesium.Cartesian2(0, 0),
                fillColor: Cesium.Color.BLUE,
                showBackground: false,
                backgroundColor: Cesium.Color.RED,
            },
        });
        return entity;
    }
    createRectangleEntity() {
        const _this = this;
        const positionList = this.positionList;
        const entity = new Cesium.Entity({
            rectangle: {
                coordinates: new Cesium.CallbackProperty(
                    () => Cesium.Rectangle.fromCartesianArray(positionList),
                    false
                ),
                material: Cesium.Color.YELLOW.withAlpha(0.5),
                outline: true,
                outlineColor: Cesium.Color.RED,
                outlineWidth: 1,
                // disableDepthTestDistance: Number.POSITIVE_INFINITY, // 始终显示在前方
                classificationType: Cesium.ClassificationType.BOTH,//贴地（绘制的面既可以贴合地形也可以贴合3D Tiles）
            },
        });
        return entity;
    }
}

/**
 * 开始绘制点
 * @param {* 是否显示测量Label} showMeasureLabel
 * @param {* 是否连续绘制} continuousDraw
 */
DrawPolygon.prototype.startDraw = function (showMeasureLabel = true, continuousDraw = true) {
    const _this = this;
    this.resetDraw(); // 重置绘制中间量
    this.tip.show('单击开始绘制');
    // 左键点击事件
    this.handler.setInputAction(event => {
        const cartesian = CesiumCoord.ScreenToCartesian3(_this.viewer, event.position); // 屏幕坐标转世界坐标
        if (!Cesium.defined(cartesian)) return;
        _this.positionList.push(cartesian.clone());
        // 测量标签
        if (showMeasureLabel && !_this.labelEntity) {
            _this.labelEntity = _this.createLabelEntity();
            _this.entityCollection.add(_this.labelEntity, _this.groupId);
        }
        // 矩形实体
        if (!_this.rectangleEntry) {
            _this.rectangleEntry = _this.createRectangleEntity();
            _this.entityCollection.add(_this.rectangleEntry, _this.groupId);
            _this.tip.changeText('再次点击结束绘制');
        } else {
            // 点击第二次结束绘制
            _this.endDraw();
            // 连续绘制
            if (continuousDraw) {
                _this.startDraw(showMeasureLabel);
            }
        }
    }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
    // 鼠标移动事件
    this.handler.setInputAction(event => {
        if (_this.rectangleEntry) {
            const cartesian = CesiumCoord.ScreenToCartesian3(_this.viewer, event.endPosition); // 屏幕坐标转世界坐标
            if (!Cesium.defined(cartesian)) return;
            const positionList = _this.positionList;
            if (positionList.length === 1) {
                positionList.push(cartesian.clone());
            } else if (positionList.length >= 2) {
                positionList.pop();
                positionList.push(cartesian.clone());
            }
        }
        const { x, y } = event.endPosition;
        _this.tip.moveTipDOMPosition(x, y); // 改变 TipDOM 位置
    }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
    // 右键点击事件
    this.handler.setInputAction(event => {
        this.endDraw();
    }, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
};

/**
 * 结束绘制点
 */
DrawPolygon.prototype.endDraw = function () {
    if (this.positionList.length < 3) {
        // 删除这次绘制结果
        this.entityCollection.remove(this.groupId);
    } else {
        this.positionList.pop(); // 删除辅助绘制点位
    }
    this.tip.close();
    this.removeCallbackProperty();
    this.handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);
    this.handler.removeInputAction(Cesium.ScreenSpaceEventType.MOUSE_MOVE);
    this.handler.removeInputAction(Cesium.ScreenSpaceEventType.RIGHT_CLICK);
};
/**
 * 清除绘制的点
 */
DrawPolygon.prototype.removeDraw = function () {
    this.entityCollection.removeAll(); // entity集合
};

/**
 * 开始绘制点 Promise 方式
 * @param {* 是否显示测量Label} showMeasureLabel
 */
DrawPolygon.prototype.drawPromise = function (showMeasureLabel = true) {
    const _this = this;
    return new Promise((resolve, reject) => {
        try {
            this.resetDraw(); // 重置绘制中间量
            this.tip.show('单击开始绘制');
            // 左键点击事件
            this.handler.setInputAction(event => {
                const cartesian = CesiumCoord.ScreenToCartesian3(_this.viewer, event.position); // 屏幕坐标转世界坐标
                if (!Cesium.defined(cartesian)) return;
                _this.positionList.push(cartesian.clone());
                // 测量标签
                if (showMeasureLabel && !_this.labelEntity) {
                    _this.labelEntity = _this.createLabelEntity();
                    _this.entityCollection.add(_this.labelEntity, _this.groupId);
                }
                // 矩形实体
                if (!_this.rectangleEntry) {
                    _this.rectangleEntry = _this.createRectangleEntity();
                    _this.entityCollection.add(_this.rectangleEntry, _this.groupId);
                    _this.tip.changeText('再次点击结束绘制');
                } else {
                    // 点击第二次结束绘制
                    _this.endDraw();
                    console.log(_this.groupId);
                    const entities = this.entityCollection.getEntitiesByGroupId(_this.groupId); // 当前绘制的所有实体
                    resolve({
                        entities,
                        positionList: JSON.parse(JSON.stringify(_this.positionList)), // 当前绘制的点坐标集合
                        rectanglePositionList: parseRectanglePosition(_this.positionList),
                    });
                }
            }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
            // 鼠标移动事件
            this.handler.setInputAction(event => {
            
                if (_this.rectangleEntry) {
                    const cartesian = CesiumCoord.ScreenToCartesian3(
                        _this.viewer,
                        event.endPosition
                    ); // 屏幕坐标转世界坐标
                    if (!Cesium.defined(cartesian)) return;
                    const positionList = _this.positionList;
                    if (positionList.length === 1) {
                        positionList.push(cartesian.clone());
                    } else if (positionList.length >= 2) {
                        positionList.pop();
                        positionList.push(cartesian.clone());
                    }
                }
                const { x, y } = event.endPosition;
                _this.tip.moveTipDOMPosition(x, y); // 改变 TipDOM 位置
            }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
            // 右键点击事件
            this.handler.setInputAction(event => {
                _this.endDraw();
                const entities = this.entityCollection.getEntitiesByGroupId(_this.groupId); // 当前绘制的所有实体
                resolve({
                    entities,
                    positionList: JSON.parse(JSON.stringify(_this.positionList)), // 当前绘制的点坐标集合
                    rectanglePositionList: parseRectanglePosition(_this.positionList),
                });
            }, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
        } catch (e) {
            reject(e);
        }
    });
};

// 根据两点绘制的矩形，返回四个顶点的经纬度坐标
function parseRectanglePosition(positionList) {
  console.log('positionList',positionList)
    const rectangleCoordinates = Cesium.Rectangle.fromCartesianArray(positionList);
    // 获取 Rectangle 的四个顶点
    const west = Cesium.Math.toDegrees(rectangleCoordinates.west);
    const south = Cesium.Math.toDegrees(rectangleCoordinates.south);
    const east = Cesium.Math.toDegrees(rectangleCoordinates.east);
    const north = Cesium.Math.toDegrees(rectangleCoordinates.north);
    // 顶点的经纬度
    const southwest = { longitude: west, latitude: south }; // 西南角
    const southeast = { longitude: east, latitude: south }; // 东南角
    const northwest = { longitude: west, latitude: north }; // 西北角
    const northeast = { longitude: east, latitude: north }; // 东北角
    // 顶点逆时针排列
    return [
        southwest.longitude,
        southwest.latitude,
        southeast.longitude,
        southeast.latitude,
        northeast.longitude,
        northeast.latitude,
        northwest.longitude,
        northwest.latitude,
    ];
}
